package com.hjrpc.babyyamall.member.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.hjrpc.babyyamall.member.constant.MemberConstant;
import com.hjrpc.babyyamall.member.dao.MemberDao;
import com.hjrpc.babyyamall.member.entity.MemberEntity;
import com.hjrpc.babyyamall.member.entity.MemberLevelEntity;
import com.hjrpc.babyyamall.member.entity.MemberSocialEntity;
import com.hjrpc.babyyamall.member.exception.MobileExistsException;
import com.hjrpc.babyyamall.member.exception.UsernameExistsException;
import com.hjrpc.babyyamall.member.service.MemberLevelService;
import com.hjrpc.babyyamall.member.service.MemberService;
import com.hjrpc.babyyamall.member.service.MemberSocialService;
import com.hjrpc.babyyamall.member.vo.WeiBoUserVo;
import com.hjrpc.common.dto.LoginUserTo;
import com.hjrpc.common.dto.MemberRegisterTo;
import com.hjrpc.common.dto.SocialUser;
import com.hjrpc.common.dto.UserLoginTo;
import com.hjrpc.common.exception.BizCodeEnum;
import com.hjrpc.common.utils.HttpUtils;
import com.hjrpc.common.utils.PageUtils;
import com.hjrpc.common.utils.Query;
import com.hjrpc.common.utils.R;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {

    @Autowired
    MemberLevelService memberLevelService;

    @Autowired
    MemberSocialService memberSocialService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public R register(MemberRegisterTo memberRegisterTo) throws MobileExistsException, UsernameExistsException {
        // 判断用户名、手机是否重复
        checkUsernameExists(memberRegisterTo.getUsername());
        checkPhoneExists(memberRegisterTo.getPhone());

        MemberEntity memberEntity = new MemberEntity();
        memberEntity.setUsername(memberRegisterTo.getUsername());
        memberEntity.setMobile(memberRegisterTo.getPhone());

        // 获取用户默认级别
        MemberLevelEntity memberLevelEntity = memberLevelService.lambdaQuery().eq(MemberLevelEntity::getDefaultStatus, 1).one();
        memberEntity.setLevelId(memberLevelEntity.getId());

        memberEntity.setCreateTime(new Date());
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        memberEntity.setPassword(passwordEncoder.encode(memberRegisterTo.getPassword()));

        // 保存用户信息
        baseMapper.insert(memberEntity);

        return R.ok();
    }

    @Override
    public R login(UserLoginTo userLoginTo) {
        // 根据用户名查询用户信息
        MemberEntity member = this.lambdaQuery().eq(MemberEntity::getUsername, userLoginTo.getLoginAccount())
                .or().eq(MemberEntity::getMobile, userLoginTo.getLoginAccount())
                .or().eq(MemberEntity::getEmail, userLoginTo.getLoginAccount()).one();
        if (member == null) {
            return R.error(BizCodeEnum.ACCOUNT_NOT_EXISTS);
        }

        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        if (!encoder.matches(userLoginTo.getPassword(), member.getPassword())) {
            return R.error(BizCodeEnum.PASSWORD_ERROR);
        }
        // 返回登录用户信息
        LoginUserTo loginUser = new LoginUserTo();
        BeanUtils.copyProperties(member, loginUser);
        return R.ok().setData(loginUser);
    }

    @Override
    public R login(SocialUser socialUser) {
        MemberSocialEntity socialEntity = memberSocialService.lambdaQuery()
                .eq(MemberSocialEntity::getUid, socialUser.getUid())
                .eq(MemberSocialEntity::getSocialType, MemberConstant.MemberSocialTypeEnum.WEIBO.getCode())
                .one();
        MemberEntity member = null;
        // 如果第一次登录，先进行注册
        if (socialEntity == null) {
            Map<String, String> querys = new HashMap<>();
            querys.put("access_token", socialUser.getAccessToken());
            querys.put("uid", socialUser.getUid());
            try {
                HttpResponse response = HttpUtils.doGet("https://api.weibo.com", "/2/users/show.json",
                        null, new HashMap<>(), querys);
                if (response.getStatusLine().getStatusCode() != 200) {
                    throw new RuntimeException("请求出现异常！");
                }
                String socialUserInfoJson = EntityUtils.toString(response.getEntity());
                Gson gson = new Gson();
                WeiBoUserVo weiBoUserVo = gson.fromJson(socialUserInfoJson, WeiBoUserVo.class);
                member = new MemberEntity();
                member.setUsername(weiBoUserVo.getName());
                member.setNickname(weiBoUserVo.getScreen_name());
                member.setCreateTime(new Date());
                member.setCity(weiBoUserVo.getCity());
                if (StringUtils.isNotBlank(weiBoUserVo.getGender())) {
                    member.setGender("m".equalsIgnoreCase(weiBoUserVo.getGender()) ? 1 : 0);
                }
                baseMapper.insert(member);

                MemberSocialEntity memberSocialEntity = new MemberSocialEntity();
                memberSocialEntity.setMemberId(member.getId());
                memberSocialEntity.setSocialType(MemberConstant.MemberSocialTypeEnum.WEIBO.getCode());
                memberSocialEntity.setExpiresin(socialUser.getExpiresIn() + "");
                memberSocialEntity.setUid(socialUser.getUid());
                memberSocialService.save(memberSocialEntity);
            } catch (Exception e) {
                e.printStackTrace();
                return R.error(e.getMessage());
            }

        } else {
            member = lambdaQuery().eq(MemberEntity::getId, socialEntity.getMemberId()).one();
        }
        LoginUserTo loginUser = new LoginUserTo();
        BeanUtils.copyProperties(member, loginUser);
        return R.ok().setData(loginUser);
    }

    private void checkPhoneExists(String phone) {
        Integer count = this.lambdaQuery().eq(MemberEntity::getMobile, phone).count();
        if (count > 0) {
            throw new MobileExistsException();
        }
    }

    private void checkUsernameExists(String username) {
        Integer count = this.lambdaQuery().eq(MemberEntity::getUsername, username).count();
        if (count > 0) {
            throw new UsernameExistsException();
        }
    }

}